function varargout = InstallationGUI(varargin) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Configures toolbox paths for pipeline and installs fixes. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright (C) 2013-2014, Michael J. Cheung % % This file is a part of the MEG & PLS Pipeline (MEGPLS). For more % details, see the documentation included with the software package. % % MEGPLS is free software: you can redistribute it and/or modify it under % the terms of the GNU General Public License version 2 as published by % the Free Software Foundation. This program is distributed in the hope % that it will be useful, but WITHOUT ANY WARRANTY; without even the % implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % See the GNU General Public License for more details. % % You should have received a copy of the GNU General Public License along % with this program. If not, you can download the license here: % . % Last Modified by GUIDE v2.5 26-Feb-2014 21:48:15 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @InstallationGUI_OpeningFcn, ... 'gui_OutputFcn', @InstallationGUI_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT %--- Executes just before InstallationGUI is made visible. ---% %---------------------------------------------------------% function InstallationGUI_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to InstallationGUI (see VARARGIN) % Choose default command line output for InstallationGUI handles.output = hObject; % Update handles structure guidata(hObject, handles); % Get pipeline run directory: [PipelineDir, ~, ~] = fileparts(which('InstallationGUI.m')); handles.PipelineDir = PipelineDir; % Initialize variables: if exist([PipelineDir,'/ToolboxPaths.mat'], 'file') ToolboxPaths = load([PipelineDir,'/ToolboxPaths.mat']); handles.paths.Fieldtrip = ToolboxPaths.paths.Fieldtrip; handles.paths.SPM = ToolboxPaths.paths.SPM; handles.paths.AFNIMatlab = ToolboxPaths.paths.AFNIMatlab; set(handles.TextboxFieldtripPath, 'String', handles.paths.Fieldtrip); set(handles.TextboxSPMPath, 'String', handles.paths.SPM); set(handles.TextboxAFNIMatlabPath, 'String', handles.paths.AFNIMatlab); else handles.paths.Fieldtrip = []; handles.paths.SPM = []; handles.paths.AFNIMatlab = []; end % Save handles: guidata(hObject, handles); % UIWAIT makes InstallationGUI wait for user response (see UIRESUME) % uiwait(handles.figure1); %--- Outputs from this function are returned to the command line. ---% %--------------------------------------------------------------------% function varargout = InstallationGUI_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; %======================================% % FUNCTIONS FOR SETTING TOOLBOX PATHS: % %======================================% %--- Executes on button press in ButtonFieldtripPath. ---% %--------------------------------------------------------% function ButtonFieldtripPath_Callback(hObject, eventdata, handles) SelectedPath = uigetdir(pwd, 'Specify Fieldtrip toolbox directory:'); if SelectedPath == 0 return; % If user cancels end % Check if selected path is Fieldtrip toolbox: if ~exist([SelectedPath,'/ft_defaults.m'], 'file') ErrMsg = {'ERROR:'; 'Selected directory does not seem to be Fieldtrip toolbox.'; 'Cannot find "ft_defaults.m" function in target location.'}; msgbox(ErrMsg, 'Error:'); return; end % Import required fieldtrip private functions: ImportFcnDir = [handles.PipelineDir,'/MEGPLS_COMPONENTS/FieldtripPrivate']; if ~exist(ImportFcnDir, 'dir') status = mkdir(ImportFcnDir); if status == 0 msgbox('Error: Failed to create folder in pipeline directory.') return; end end if exist([ImportFcnDir,'/parameterselection.m'], 'file'); delete([ImportFcnDir,'/parameterselection.m']); end if exist([ImportFcnDir,'/align_ijk2xyz.m'], 'file'); delete([ImportFcnDir,'/align_ijk2xyz.m']); end status1 = copyfile([SelectedPath,'/private/parameterselection.m'], [ImportFcnDir,'/'], 'f'); status2 = copyfile([SelectedPath,'/private/align_ijk2xyz.m'], [ImportFcnDir,'/'], 'f'); if status1 == 0 || status2 == 0 msgbox('Error: Failed to import Fieldtrip private functions.') return; end % Set fieldtrip path: handles.paths.Fieldtrip = SelectedPath; set(handles.TextboxFieldtripPath, 'String', handles.paths.Fieldtrip); % Save handles: guidata(hObject, handles); %--- Textbox to display selected Fieldtrip path: ---% %---------------------------------------------------% function TextboxFieldtripPath_Callback(hObject, eventdata, handles) EnteredText = get(handles.TextboxFieldtripPath, 'String'); if ~isequal(EnteredText, handles.paths.Fieldtrip); set(handles.TextboxFieldtripPath, 'String', handles.paths.Fieldtrip); msgbox('Note: Use button to change Fieldtrip path.') end %--- Executes on button press in ButtonSPMPath. ---% %--------------------------------------------------% function ButtonSPMPath_Callback(hObject, eventdata, handles) SelectedPath = uigetdir(pwd, 'Specify SPM8 toolbox directory:'); if SelectedPath == 0 return; % If user cancels end % Check if selected path is SPM toolbox: if ~exist([SelectedPath,'/spm_get_defaults.m'], 'file') ErrMsg = {'ERROR:'; 'Selected directory does not seem to be SPM8 toolbox.'; 'Cannot find "spm_get_defaults.m" function in target location.'}; msgbox(ErrMsg, 'Error:'); return; end % Set SPM path: handles.paths.SPM = SelectedPath; set(handles.TextboxSPMPath, 'String', handles.paths.SPM); % Save handles: guidata(hObject, handles); %--- Textbox to display selected SPM path: ---% %---------------------------------------------% function TextboxSPMPath_Callback(hObject, eventdata, handles) EnteredText = get(handles.TextboxSPMPath, 'String'); if ~isequal(EnteredText, handles.paths.SPM); set(handles.TextboxSPMPath, 'String', handles.paths.SPM); msgbox('Note: Use button to change SPM path.') end %--- Executes on button press in ButtonAFNIMatlabPath. ---% %---------------------------------------------------------% function ButtonAFNIMatlabPath_Callback(hObject, eventdata, handles) SelectedPath = uigetdir(pwd, 'Specify AFNI-Matlab toolbox directory:'); if SelectedPath == 0 return; % If user cancels end % Check if selected path is AFNI-Matlab toolbox: if ~exist([SelectedPath,'/BrikLoad.m'], 'file') ErrMsg = {'ERROR:'; 'Selected directory does not seem to be AFNI-Matlab toolbox.'; 'Cannot find "BrikLoad.m" function in target location.'}; msgbox(ErrMsg, 'Error:'); return; end % Set AFNI-Matlab path: handles.paths.AFNIMatlab = SelectedPath; set(handles.TextboxAFNIMatlabPath, 'String', handles.paths.AFNIMatlab); % Save handles: guidata(hObject, handles); %--- Textbox to display selected AFNI-Matlab path: ---% %-----------------------------------------------------% function TextboxAFNIMatlabPath_Callback(hObject, eventdata, handles) EnteredText = get(handles.TextboxAFNIMatlabPath, 'String'); if ~isequal(EnteredText, handles.paths.AFNIMatlab); set(handles.TextboxAFNIMatlabPath, 'String', handles.paths.AFNIMatlab); msgbox('Note: Use button to change AFNI-Matlab path.') end %--- Executes on button press in ButtonSaveSettings. ---% %-------------------------------------------------------% function ButtonSaveSettings_Callback(hObject, eventdata, handles) if isempty(handles.paths.Fieldtrip) msgbox('Warning: Fieldtrip path has not been set.', 'Warning:'); return; end if isempty(handles.paths.SPM) msgbox('Warning: SPM path has not been set.', 'Warning:'); return; end if isempty(handles.paths.AFNIMatlab) msgbox('Warning: AFNI-Matlab path has not been set.', 'Warning:'); return; end % Install fixes: Success = MEGPLS_Install_Fixes(handles); if Success == 0 return; end % Remove existing .mat: if exist([handles.PipelineDir,'/ToolboxPaths.mat'], 'file') delete([handles.PipelineDir,'/ToolboxPaths.mat']); if exist([handles.PipelineDir,'/ToolboxPaths.mat'], 'file') msgbox('Error: Failed to remove previous ToolboxPaths.mat for overwrite.', 'Error:') return; end end % Save paths to .mat: paths = handles.paths; save([handles.PipelineDir,'/ToolboxPaths.mat'], 'paths'); % Addpaths: addpath(genpath(handles.PipelineDir)); rmpath([handles.PipelineDir,'/DEFAULT_SETTINGS']); % Only want to call the ones in AnalysisID rmpath([handles.PipelineDir,'/TEMPORARY_FIXES']); % Want to call from Fieldtrip toolbox addpath([paths.Fieldtrip,'/']); ft_defaults; addpath([paths.SPM,'/']); addpath([paths.AFNIMatlab,'/']); % Feedback: if exist([handles.PipelineDir,'/ToolboxPaths.mat'], 'file') msgbox('Toolbox paths successfully saved.'); end %--- Executes on button press in ButtonUninstallFixes. ---% %---------------------------------------------------------% function ButtonUninstallFixes_Callback(hObject, eventdata, handles) Success = MEGPLS_Uninstall_Fixes(handles); if Success == 0 return; else msgbox('MEGPLS compatibility fixes successfully uninstalled.'); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % FUNCTIONS FOR MEGPLS COMPATIBILITY FIXES: % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %--- Installs compatibility fixes: ---% %-------------------------------------% function Success = MEGPLS_Install_Fixes(InputHandles) handles = InputHandles; paths = handles.paths; InstallErrMsg = {'Error:'; ''; 'Failed to apply FieldTrip compatibility patch for [MEG]PLS pipeline.'; 'Ensure you have read/write permissions to Fieldtrip and [MEG]PLS folders.'; 'For more details, see README file in "TEMPORARY_FIXES" folder.'}; FixBackupFolder = [paths.Fieldtrip,'/MEGPLS_INSTALL_BACKUP']; if ~exist(FixBackupFolder, 'dir') Status = mkdir(FixBackupFolder); if Status == 0 msgbox(InstallErrMsg, 'Error:'); Success = 0; return; end end % Apply temporary "warning_once" fix (See readme in "TEMPORARY_FIXES" folder): % Bug in newer version of FT "warning_once.m" that occurs when calling from MATLAB GUIDE. % Link: http://mailman.science.ru.nl/pipermail/fieldtrip/2013-August/006889.html % Backup original file: if ~exist([FixBackupFolder,'/warning_once.m'], 'file') TargetFile = [paths.Fieldtrip,'/private/warning_once.m']; if ~exist(TargetFile, 'file') msgbox('Error: Failed to find original "warning_once.m" file.', 'Error:') msgbox(InstallErrMsg, 'Error:') Success = 0; return; end MakeBackup = copyfile(TargetFile, [FixBackupFolder,'/'], 'f'); if MakeBackup == 0 msgbox('Error: Failed to create backup of original "warning_once.m" file.', 'Error:') msgbox(InstallErrMsg, 'Error:') Success = 0; return; end end % Apply fixed files (overwrite if needed): FixedFile = [handles.PipelineDir,'/TEMPORARY_FIXES/warning_once_20130211.m']; if exist([paths.Fieldtrip,'/private/warning_once.m'], 'file') delete([paths.Fieldtrip,'/private/warning_once.m']); if exist([paths.Fieldtrip,'/private/warning_once.m'], 'file') msgbox('Error: Failed to remove previous "warning_once.m" files for overwrite.', 'Error:') msgbox(InstallErrMsg, 'Error:') Success = 0; return; end Copy1 = copyfile(FixedFile, [paths.Fieldtrip,'/private/warning_once.m'], 'f'); else Copy1 = 1; end if exist([paths.Fieldtrip,'/utilities/private/warning_once.m'], 'file') delete([paths.Fieldtrip,'/utilities/private/warning_once.m']); if exist([paths.Fieldtrip,'/utilities/private/warning_once.m'], 'file') msgbox('Error: Failed to remove previous "warning_once.m" files for overwrite.', 'Error:') msgbox(InstallErrMsg, 'Error:') Success = 0; return; end Copy2 = copyfile(FixedFile, [paths.Fieldtrip,'/utilities/private/warning_once.m'], 'f'); else Copy2 = 1; end if exist([paths.Fieldtrip,'/specest/private/warning_once.m'], 'file') delete([paths.Fieldtrip,'/specest/private/warning_once.m']); if exist([paths.Fieldtrip,'/specest/private/warning_once.m'], 'file') msgbox('Error: Failed to remove previous "warning_once.m" files for overwrite.', 'Error:') msgbox(InstallErrMsg, 'Error:') Success = 0; return; end Copy3 = copyfile(FixedFile, [paths.Fieldtrip,'/specest/private/warning_once.m'], 'f'); else Copy3 = 1; end if Copy1 == 0 || Copy2 == 0 || Copy3 == 0 msgbox(InstallErrMsg, 'Error:'); Success = 0; return; end % Apply temporary "ft_postamble_history" fix (See readme in "TEMPORARY_FIXES" folder): % Bug in newer version of FT "warning_once.m" that occurs when calling from MATLAB GUIDE. % Link: http://mailman.science.ru.nl/pipermail/fieldtrip/2013-August/006889.html % Backup original file: if ~exist([FixBackupFolder,'/ft_postamble_history.m'], 'file') TargetFile = [paths.Fieldtrip,'/utilities/private/ft_postamble_history.m']; if ~exist(TargetFile, 'file') msgbox('Error: Failed to find original "ft_postamble_history.m" file.', 'Error:') msgbox(InstallErrMsg, 'Error:') Success = 0; return; end MakeBackup = copyfile(TargetFile, [FixBackupFolder,'/'], 'f'); if MakeBackup == 0 msgbox(InstallErrMsg, 'Error:') Success = 0; return; end end % Apply fixed files (overwrite if needed): FixedFile = [handles.PipelineDir,'/TEMPORARY_FIXES/ft_postamble_history_20130211.m']; if exist([paths.Fieldtrip,'/utilities/private/ft_postamble_history.m'], 'file') delete([paths.Fieldtrip,'/utilities/private/ft_postamble_history.m']); if exist([paths.Fieldtrip,'/utilities/private/ft_postamble_history.m'], 'file') msgbox('Error: Failed to remove previous "ft_postamble_history.m" for overwrite.', 'Error:') msgbox(InstallErrMsg, 'Error:') Success = 0; return; end end Copy = copyfile(FixedFile, ... [paths.Fieldtrip,'/utilities/private/ft_postamble_history.m'], 'f'); if Copy == 0 msgbox(InstallErrMsg, 'Error:'); Success = 0; return; end % Add legend functionality to "ft_singleplotER" function. % (So children of interactive multiplot have legends applied). if ~exist([FixBackupFolder,'/ft_singleplotER.m'], 'file') TargetFile = [paths.Fieldtrip,'/ft_singleplotER.m']; if ~exist(TargetFile, 'file') msgbox('Error: Failed to find original "ft_singleplotER.m" file.', 'Error:') msgbox(InstallErrMsg, 'Error:') Success = 0; return; end MakeBackup = copyfile(TargetFile, [FixBackupFolder,'/'], 'f'); if MakeBackup == 0 msgbox(InstallErrMsg, 'Error:') Success = 0; return; end % Add fix to file once: TempPathFT = strrep(paths.Fieldtrip, ' ', '\ '); % Replace spaces with "\ " for unix. system(['sed -i "/ft_postamble previous/ a\ \n'... 'if isfield(cfg, ''legend'')\n'... ' if numel(cfg.legend) ~= Ndata\n'... ' disp(''Warning: # legend inputs does not match # datasets.'')\n'... ' end\n'... ' clickableLegend(cfg.legend, ''interpreter'', ''none'');\n'... 'end\n\n" ',TempPathFT,'/ft_singleplotER.m']) % SED function to add text after match: % Format: sed -i '/regexp-string-to-match/ a\ string-to-append' filename % Note: a\ option is used to append text after line of address match. end Success = 1; %--- Uninstalls compatibility fixes: ---% %---------------------------------------% function Success = MEGPLS_Uninstall_Fixes(InputHandles) handles = InputHandles; paths = handles.paths; UninstallErrMsg = {'Error:'; ''; 'Failed to uninstall compatibility fixes for MEGPLS pipeline.'; 'Check permissions on Fieldtrip and MEGPLS pipeline folders.'; 'See README file in "TEMPORARY_FIXES" folder.'}; FixBackupFolder = [paths.Fieldtrip,'/MEGPLS_INSTALL_BACKUP']; % Uninstall "warning_once.m" fix: BackupFile = [FixBackupFolder,'/warning_once.m']; if exist(BackupFile, 'file') if exist([paths.Fieldtrip,'/private/warning_once.m'], 'file') delete([paths.Fieldtrip,'/private/warning_once.m']); if exist([paths.Fieldtrip,'/private/warning_once.m'], 'file') msgbox('Error: Failed to remove "warning_once.m" files for uninstall.', 'Error:') msgbox(UninstallErrMsg, 'Error:') Success = 0; return; end Restore1 = copyfile(BackupFile, [paths.Fieldtrip,'/private/warning_once.m'], 'f'); else Restore1 = 1; end if exist([paths.Fieldtrip,'/utilities/private/warning_once.m'], 'file') delete([paths.Fieldtrip,'/utilities/private/warning_once.m']); if exist([paths.Fieldtrip,'/utilities/private/warning_once.m'], 'file') msgbox('Error: Failed to remove "warning_once.m" files for uninstall.', 'Error:') msgbox(UninstallErrMsg, 'Error:') Success = 0; return; end Restore2 = copyfile(BackupFile, [paths.Fieldtrip,'/utilities/private/warning_once.m'], 'f'); else Restore2 = 1; end if exist([paths.Fieldtrip,'/specest/private/warning_once.m'], 'file') delete([paths.Fieldtrip,'/specest/private/warning_once.m']); if exist([paths.Fieldtrip,'/specest/private/warning_once.m'], 'file') msgbox('Error: Failed to remove "warning_once.m" files for uninstall.', 'Error:') msgbox(UninstallErrMsg, 'Error:') Success = 0; return; end Restore3 = copyfile(BackupFile, [paths.Fieldtrip,'/specest/private/warning_once.m'], 'f'); else Restore3 = 1; end if Restore1 == 0 || Restore2 == 0 || Restore3 == 0 msgbox(UninstallErrMsg, 'Error:'); Success = 0; return; end end % Uninstall "ft_postamble_history" fix: BackupFile = [FixBackupFolder,'/ft_postamble_history.m']; if exist(BackupFile, 'file') delete([paths.Fieldtrip,'/utilities/private/ft_postamble_history.m']); if exist([paths.Fieldtrip,'/utilities/private/ft_postamble_history.m'], 'file') msgbox('Error: Failed to remove "ft_postamble_history.m" files for uninstall.', 'Error') msgbox(UninstallErrMsg, 'Error:') Success = 0; return; end Restore = copyfile(BackupFile, ... [paths.Fieldtrip,'/utilities/private/ft_postamble_history.m'], 'f'); if Restore == 0 msgbox(UninstallErrMsg, 'Error:'); Success = 0; return; end end % Uninstall "ft_singleplotER" legend modification: BackupFile = [FixBackupFolder,'/ft_singleplotER.m']; if exist(BackupFile, 'file') delete([paths.Fieldtrip,'/ft_singleplotER.m']); if exist([paths.Fieldtrip,'/ft_singleplotER.m'], 'file') msgbox('Error: Failed to remove "ft_singleplotER.m" file for uninstall.', 'Error:') msgbox(UninstallErrMsg, 'Error:') Success = 0; return; end Restore = copyfile(BackupFile, [paths.Fieldtrip,'/ft_singleplotER.m'], 'f'); if Restore == 0 msgbox(UninstallErrMsg, 'Error:'); Success = 0; return; end end % Remove ToolboxPaths.mat file: ToolboxPathsFile = [handles.PipelineDir,'/ToolboxPaths.mat']; if exist(ToolboxPathsFile, 'file') delete(ToolboxPathsFile); if exist(ToolboxPathsFile, 'file') msgbox('Error: Failed to remove ToolboxPaths.mat file for uninstall.', 'Error:') return; end end if exist(FixBackupFolder, 'dir') rmdir(FixBackupFolder, 's'); end Success = 1; %============================% % GUIDE CREATEGUI FUNCTIONS: % %============================% % --- Executes during object creation, after setting all properties. function TextboxFieldtripPath_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxSPMPath_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function TextboxAFNIMatlabPath_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end